package com.transaction.demo.task.biz.impl;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;

import com.google.gson.reflect.TypeToken;
import com.transaction.demo.common.util.JsonUtils;
import com.transaction.demo.message.MessageService;
import com.transaction.demo.message.TradePaymentManagerService;
import com.transaction.demo.message.TradePaymentQueryService;
import com.transaction.demo.message.vo.req.TransactionMessageAddReqVo;
import com.transaction.demo.message.vo.resp.TransactionMessageRespVo;
import com.transaction.demo.task.biz.TransactionMessageBiz;
import com.transaction.demo.task.config.TaskConfig;
import com.transaction.demo.trade.enums.TradeStatusEnum;
import com.transaction.demo.trade.vo.req.TradePaymentRecordReqVo;
import com.transaction.demo.trade.vo.resp.TradePaymentRecordRespVo;

/**
 * 描述：
 * 作者：马庆智
 * 日期：2023/04/26 10:29:01
 */
@Slf4j
@Service
public class TransactionMessageBizImpl implements TransactionMessageBiz {

	@Autowired
	private MessageService messageService;

	@Autowired
	private TradePaymentManagerService tradePaymentManagerService;

	@Autowired
	private TradePaymentQueryService tradePaymentQueryService;

	@Autowired
	private TaskConfig config;

	/**
	 * 处理状态为“待确认”但已超时的消息.
	 *
	 * @author 马庆智
	 * @date: 2023/4/27 14:34
	 */
	@Override
	public void handleWaitingConfirmTimeOutMessages(List<TransactionMessageRespVo> list) {
		log.info("开始处理[waiting_confirm]状态的消息,总条数[" + list.size() + "]");

		for (TransactionMessageRespVo message : list) {
			try {
				log.info("开始处理[waiting_confirm]消息ID为[" + message.getMessageId() + "]的消息");
				Map<String, String> params = JsonUtils.fromJson(message.getMessageBody(),
						new TypeToken<Map<String, String>>() {
						}.getType());

				String businessId = params.get("businessId");
				TradePaymentRecordRespVo record = tradePaymentQueryService.query(
						TradePaymentRecordReqVo.builder().bankOrderNo(businessId).build());
				log.info("订单支付信息: {}", JsonUtils.toJson(record));

				if (TradeStatusEnum.SUCCESS.name().equals(record.getStatus())) {
					log.info("订单支付成功,确认并发送[waiting_confirm]消息id[" + message.getMessageId() + "]的消息");
					messageService.confirmAndSendMessage(message.getMessageId());
				}

				if (TradeStatusEnum.WAITING_PAYMENT.name().equals(record.getStatus())) {
					log.info("订单没有支付成功,删除[waiting_confirm]消息id[" + message.getMessageId() + "]的消息");
					messageService.deleteMessageByMessageId(message.getMessageId());
				}

				log.info("结束处理[waiting_confirm]消息ID为[" + message.getMessageId() + "]的消息");
			} catch (Exception e) {
				log.error("处理[waiting_confirm]消息ID为[" + message.getMessageId() + "]的消息异常：", e);
			}
		}

	}

	/**
	 * 处理状态为“发送中”但超时没有被成功消费确认的消息
	 *
	 * @author 马庆智
	 * @date: 2023/4/27 14:35
	 */
	@Override
	public void handleSendingTimeOutMessage(List<TransactionMessageRespVo> list) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		log.debug("开始处理[SENDING]状态的消息,总条数[" + list.size() + "]");

		for (TransactionMessageRespVo message : list) {
			try {
				log.debug("开始处理[SENDING]消息ID为[" + message.getMessageId() + "]的消息");

				log.debug("[SENDING]消息ID为[" + message.getMessageId() + "]的消息,已经重新发送的次数[" + message.getMessageSendTimes() + "]");

				// 如果超过最大发送次数直接退出
				if (config.maxTimes<message.getMessageSendTimes()) {
					// 标记为死亡
					messageService.setMessageToAreadlyDead(message.getMessageId());
					continue;
				}

				// 判断是否达到发送消息的时间间隔条件
				int reSendTimes = message.getMessageSendTimes();
				int times = config.timeMap.get(reSendTimes == 0 ? 1 : reSendTimes);
				long currentTimeInMillis = Calendar.getInstance().getTimeInMillis();
				long needTime = currentTimeInMillis - (long) times * 60 * 1000;
				long hasTime = message.getUpdateTime().getTime();
				// 判断是否达到了可以再次发送的时间条件
				if (hasTime > needTime) {
					log.debug("currentTime[" + sdf.format(new Date()) + "],[SENDING]消息上次发送时间[" + sdf.format(message.getUpdateTime()) + "],必须过了[" + times + "]分钟才可以再发送。");
					continue;
				}

				// 重新发送消息
				TransactionMessageAddReqVo addReqVo = new TransactionMessageAddReqVo();
				BeanUtils.copyProperties(message,addReqVo);
				messageService.reSendMessage(addReqVo);
				log.debug("结束处理[SENDING]消息ID为[" + message.getMessageId() + "]的消息");
			} catch (Exception e) {
				log.error("处理[SENDING]消息ID为[" + message.getMessageId() + "]的消息异常：", e);
			}
		}
	}
}